package com.notes.algo.t8;

import java.util.*;

/**
 * @author
 * @Describe
 * @date
 */
public class Solution7 {
    public static void main(String[] args) {
        //假数据
        String rootId = "000000";
        String rootId2 = "000002";
        List<Map<String, Object>> dataList = new ArrayList<>();
        dataList.add(new HashMap<String, Object>() {{
            put("id", "2");
            put("pid", "1");
            put("name", "部门1");
        }});
        dataList.add(new HashMap<String, Object>() {{
            put("id", "1");
            put("pid", rootId);
            put("name", "公司根节点");
        }});
        dataList.add(new HashMap<String, Object>() {{
            put("id", "6");
            put("pid", rootId);
            put("name", "部门3");
        }});
        dataList.add(new HashMap<String, Object>() {{
            put("id", "7");
            put("pid", 6);
            put("name", "部门3小组1");
        }});
        dataList.add(new HashMap<String, Object>() {{
            put("id", "3");
            put("pid", "1");
            put("name", "部门2");
        }});
        dataList.add(new HashMap<String, Object>() {{
            put("id", "4");
            put("pid", "2");
            put("name", "部门1小组1");
        }});
        dataList.add(new HashMap<String, Object>() {{
            put("id", "5");
            put("pid", "3");
            put("name", "部门2小组1");
        }});

        //dataList为假数据，正常数据库查询所有数据。。。
        // List<Map<String, Object>> treeList = doTreeList(dataList, rootId);
        // List<Map<String, Object>> treeList2 = doTreeList(dataList, rootId2);
        /*Map<String, Set<String>> stringSetMap = doTreeList2(dataList);
        Map<String, Set<String>> stringSetMap3 = doTreeList3(dataList);*/
        // List<Map<String, Object>> treeList = doTreeList(dataList, rootId);
        LinkedList<Map<String, Object>> dataList2 = new LinkedList<Map<String, Object>>();

        // List<Map<String, Object>> treeList1 = getTreeList2(treeList, dataList2);
        handleTreeList(dataList, rootId, dataList2);
        System.out.println(dataList2);

//        Map<String, Set<String>> stringSetMap = doTreeList4(dataList);
//        System.out.println(stringSetMap);

        //输出
		/*
		[{"children":[{"children":[{"children":[],"name":"部门1小组1","pid":"2","id":"4"}],"name":"部门1","pid":"1","id":"2"},
		{"children":[{"children":[],"name":"部门2小组1","pid":"3","id":"5"}],
		"name":"部门2","pid":"1","id":"3"}],"name":"公司根节点","pid":"","id":"1"}]
		*/

    }

    public static List<Map<String, Object>> getTreeList(List<Map<String, Object>> treeList, LinkedList<Map<String, Object>> dataList) {
        for (Map<String, Object> data : treeList) {
            Map<String, Object> d = new HashMap<>();
            d.put("id", data.get("id"));
            d.put("pid", data.get("pid"));
            d.put("name", data.get("name"));
            dataList.add(d);
            List<Map<String, Object>> children = (List) data.get("children");
            if (children.size() != 0) {
                getTreeList(children, dataList);
            }
        }

        return dataList;
    }

    public static List<Map<String, Object>> getTreeList2(List<Map<String, Object>> treeList, LinkedList<Map<String, Object>> dataList) {
        for (Map<String, Object> data : treeList) {
            Map<String, Object> d = new HashMap<>();
            d.put("id", data.get("id"));
            d.put("pid", data.get("pid"));
            d.put("name", data.get("name"));
            dataList.add(d);
        }

        for (Map<String, Object> data : treeList) {
            List<Map<String, Object>> children = (List) data.get("children");
            if (children.size() != 0) {
                getTreeList(children, dataList);
            }
        }

        return dataList;
    }

    public static void handleTreeList(List<Map<String, Object>> dataList, String pid, LinkedList<Map<String, Object>> resultList) {
        if (dataList != null) {
            for (Map<String, Object> item : dataList) {
                String pid1 = item.get("pid").toString();
                if (pid.equals(pid1)) {
                    resultList.add(item);
                    String id = item.get("id").toString();
                    System.out.println("开始查找节点->" + id + "的子节点数据，该节点的父节点是->" + pid1);
                    handleTreeList(dataList, id, resultList);
                    // List<Map<String, Object>> children = handleTreeList(dataList, id);
                    // item.put("children", children);
                    // resultList.add(item);
                }
            }
        }
    }

    /**
     * 递归tree树
     *
     * @param dataList
     * @param pid
     * @return
     */
    public static List<Map<String, Object>> doTreeList(List<Map<String, Object>> dataList, String pid) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        if (dataList != null) {
            for (Map<String, Object> item : dataList) {
                String pid1 = item.get("pid").toString();
                if (pid.equals(pid1)) {
                    String id = item.get("id").toString();
                    System.out.println("开始查找节点->" + id + "的子节点数据，该节点的父节点是->" + pid1);
                    List<Map<String, Object>> children = doTreeList(dataList, id);
                    item.put("children", children);
                    resultList.add(item);
                }
            }
        }
        return resultList;
    }

    public static Map<String, Set<String>> doTreeList2(List<Map<String, Object>> dataList) {
        Map<String, Set<String>> result = new HashMap<>();
        // 所有节点编号
        Set<String> allIds = new HashSet<>();
        Set<String> dataIds = new HashSet<>();
        Map<String, Map<String, Object>> ss = new HashMap<>();
        if (dataList != null) {
            for (Map<String, Object> item : dataList) {
                String curId = item.get("id").toString();
                String curPid = item.get("pid").toString();
                dataIds.add(curId);
                allIds.add(curId);
                allIds.add(curPid);
                ss.put(curId, item);
            }
        }

        System.out.println(allIds.size() + " = " + allIds);
        System.out.println(dataIds.size() + " = " + dataIds);
        Set<String> rootIds = new HashSet<>();
        rootIds.addAll(allIds);
        rootIds.removeAll(dataIds);

        System.out.println(rootIds.size() + " = " + rootIds);
        if (rootIds.size() != 1) {
            System.out.println("当前文件对应的根节点数据错误！");
        }

        return result;
    }

    public static Map<String, Set<String>> doTreeList3(List<Map<String, Object>> dataList) {
        Map<String, Set<String>> result = new HashMap<>();
        // 所有节点编号
        Set<String> rootIds = new HashSet<>();
        Map<String, Map<String, Object>> ss = new HashMap<>();
        if (dataList != null) {
            for (Map<String, Object> item : dataList) {
                String curId = item.get("id").toString();
                String curPid = item.get("pid").toString();
                rootIds.add(curId);
                rootIds.add(curPid);
                ss.put(curId, item);
            }
        }

        System.out.println(rootIds);
        System.out.println(ss);

        if (dataList != null) {
            for (String rootId : rootIds) {
                Set<String> stringSet;
                for (Map<String, Object> item : dataList) {
                    String curPid = item.get("pid").toString();
                    String curId = item.get("id").toString();
                    if (curPid.equals(rootId)) {
                        System.out.println("根节点 -> " + rootId + "存在子节点->" + curId);
                        stringSet = result.get(rootId);
                        if (null != stringSet && stringSet.size() > 0) {
                            stringSet.add(curId);
                            result.put(rootId, stringSet);
                        } else {
                            stringSet = new HashSet<>();
                            stringSet.add(curId);
                            result.put(rootId, stringSet);
                        }
                    }
                }
            }
        }

        Set<String> sss = new HashSet<>();
        result.forEach((k, v) -> {
            if (null == ss.get(k)) {
                sss.add(k);
            }
        });

        System.out.println(sss);
        if (sss.size() > 1) {
            System.out.println("存在多个根节点 -> " + sss);
        }

        return result;
    }

    public static Map<String, Set<String>> doTreeList4(List<Map<String, Object>> dataList) {
        Map<String, Set<String>> result = new HashMap<>();
        // 所有节点编号
        Set<String> allIds = new HashSet<>();
        Set<String> dataIds = new HashSet<>();
        Map<String, Map<String, Object>> ss = new HashMap<>();
        if (dataList != null) {
            for (Map<String, Object> item : dataList) {
                String curId = item.get("id").toString();
                String curPid = item.get("pid").toString();
                dataIds.add(curId);
                allIds.add(curId);
                allIds.add(curPid);
                ss.put(curId, item);
            }
        }

        System.out.println(allIds.size() + " = " + allIds);
        System.out.println(dataIds.size() + " = " + dataIds);

        for (String rootId : allIds) {
            Set<String> stringSet;
            for (Map<String, Object> item : dataList) {
                String curPid = item.get("pid").toString();
                String curId = item.get("id").toString();
                if (curPid.equals(rootId)) {
                    System.out.println("根节点 -> " + rootId + "存在子节点->" + curId);
                    stringSet = result.get(rootId);
                    if (null != stringSet && stringSet.size() > 0) {
                        stringSet.add(curId);
                        result.put(rootId, stringSet);
                    } else {
                        stringSet = new HashSet<>();
                        stringSet.add(curId);
                        result.put(rootId, stringSet);
                    }
                }
            }
        }
        System.out.println(result);

        Set<String> rootIds = new HashSet<>();
        rootIds.addAll(allIds);
        rootIds.removeAll(dataIds);

        System.out.println(rootIds.size() + " = " + rootIds);
        if (rootIds.size() != 1) {
            System.out.println("当前文件对应的根节点数据错误！");
            throw new RuntimeException("当前文件对应的根节点数据错误！");
        }

        String rootId = rootIds.iterator().next();
        Set<String> strings = result.get(rootId);
        /*LinkedList<Map<String, Object>> rs = new LinkedList<Map<String, Object>>();
        for (String s : strings) {
            Map<String, Object> stringObjectMap = ss.get(s);
            rs.add(stringObjectMap);
            String id = String.valueOf(stringObjectMap.get("id"));
        }
        while (null != result.get(rootId)) {
            Set<String> strings2 = result.get(rootId);
            for (String s : strings2) {
                Set<String> strings1 = result.get(s);
            }
        }*/
        LinkedHashSet set = new LinkedHashSet();
        hand(rootId, result, set);
        System.out.println(set);

        return result;
    }

    public static void hand(String rootId, Map<String, Set<String>> result, LinkedHashSet set) {
        Set<String> strings = result.get(rootId);
        if (null == strings) {
            System.out.println(rootId + "无子节点");
            return;
        }
        Iterator<String> iterator = strings.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            set.add(next);
        }

        Iterator<String> iterator2 = strings.iterator();
        while (iterator2.hasNext()) {
            String next = iterator2.next();
            hand(next, result, set);
        }
    }

    private void doTreeList(Map<String, List<Map<String, Object>>> parentIdMap, String rootId,
                            LinkedList<Map<String, Object>> result) {
        if (parentIdMap.containsKey(rootId)) {
            List<Map<String, Object>> treeDataList = parentIdMap.get(rootId);
            result.addAll(treeDataList);
            for (Map<String, Object> treeData : treeDataList) {
                doTreeList(parentIdMap, String.valueOf(treeData.get("pid")), result);
            }
        } else {
            System.out.println(rootId + "不存在");
        }
    }
}
